using System;
using System.Collections.ObjectModel;
using System.Windows.Threading;

namespace HabilisDesign.Iota
{
    public class StatusCollection : ObservableCollection<Status>
    {
        #region Fields

        private int m_MaxSize = 20;
        private DateTime m_LastUpdated = DateTime.MinValue;
        private Dispatcher m_Dispatcher;
        private delegate void AddCallback( Status status, bool addToTop );

        #endregion

        #region Properties

        public int MaxSize
        {
            get
            {
                return m_MaxSize;
            }
            set
            {
                m_MaxSize = value;
            }
        }

        public DateTime LastUpdated
        {
            get
            {
                return m_LastUpdated;
            }
            set
            {
                m_LastUpdated = value;
            }
        }

        #endregion

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the StatusCollection class.
        /// </summary>
        public StatusCollection()
        {
        }

        /// <summary>
        /// Initializes a new instance of the StatusCollection class.
        /// </summary>
        public StatusCollection( Dispatcher dispatcher )
        {
            m_Dispatcher = dispatcher;
        }

        #endregion

        #region Methods

		/// <summary>
		/// Adds the specified status.
		/// </summary>
		/// <param name="status">The status.</param>
		/// <param name="addToTop">if set to <c>true</c> [add to top].</param>
		private void Add( Status status, bool addToTop )
		{
			if ( m_Dispatcher == null || m_Dispatcher.CheckAccess() )
			{
				if ( this.Contains( status ) )
				{
					return;
				}
				if ( Count >= m_MaxSize )
				{
					base.RemoveItem( Count - 1 );
				}
				if ( addToTop )
				{
					base.InsertItem( 0, status );
				}
				else
				{
					base.Add( status );
				}
				m_LastUpdated = DateTime.Now;
			}
			else
			{
				m_Dispatcher.BeginInvoke( DispatcherPriority.Send, new AddCallback( Add ), status, addToTop );
			}
		}

		/// <summary>
		/// Adds the specified status.
		/// </summary>
		/// <param name="status">The status.</param>
        public new void Add( Status status )
        {
            Add( status, false );
        }

		/// <summary>
		/// Determines whether an element is in the <see cref="T:System.Collections.ObjectModel.Collection`1"></see>.
		/// </summary>
		/// <param name="item">The object to locate in the <see cref="T:System.Collections.ObjectModel.Collection`1"></see>. The value can be null for reference types.</param>
		/// <returns>
		/// true if item is found in the <see cref="T:System.Collections.ObjectModel.Collection`1"></see>; otherwise, false.
		/// </returns>
        public new bool Contains( Status item )
        {
            foreach ( Status currentItem in base.Items )
            {
                if ( item.Id == currentItem.Id )
                {
                    return true;
                }
            }
            return false;
        }

		/// <summary>
		/// Inserts the specified status.
		/// </summary>
		/// <param name="status">The status.</param>
		public void Insert( Status status )
		{
			Add( status, true );
		}

		/// <summary>
		/// Removes all elements from the <see cref="T:System.Collections.ObjectModel.Collection`1"></see>.
		/// </summary>
		public new void Clear()
		{
			m_LastUpdated = DateTime.MinValue;
			base.Clear();
		}

        #endregion

    } // end class

} // end namespace
